#pragma once

#include <iostream>
#include <sys/epoll.h>
#include <unistd.h>

class Epoller
{
public:
    Epoller()
        : _epfd(-1)
    {
        _epfd = epoll_create(128);
        if(_epfd < 0)
        {
            std::cout << "epoll_create fail" << std::endl;
            exit(-1);
        }
        std::cout << "epoll_create sucess: " << _epfd << std::endl; 
    }

    void AddEvent(int sockfd, uint32_t events)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        ev.events = events;
        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sockfd, &ev);
        if(n < 0)
        {
            std::cout << "epoll_ctl error" << std::endl;
            return;
        }
        std::cout << "epoll_ctl success: " << sockfd << std::endl;
    }

    void DelEvent(int sockfd)
    {
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sockfd, nullptr);
        std::cout << "delete sockfd sucess" << std::endl;
    }

    void ModEvent(int sockfd, uint32_t new_event)
    {
        struct epoll_event ev;
        ev.data.fd = sockfd;
        ev.events = new_event;
        int n = epoll_ctl(_epfd, EPOLL_CTL_MOD, sockfd, &ev);
        if(n < 0)
        {
            std::cout << "ModEvent fail" << std::endl;
            return;
        }
        std::cout << "ModEvent success" << std::endl;
    }

    int WaitEvents(struct epoll_event revs[], int maxnum, int timeout)
    {
        int n = epoll_wait(_epfd, revs, maxnum, timeout);
        if(n < 0)
        {
            std::cout << "epoll_wait error" << std::endl;
            return 0;
        }
        return n;
    }

    ~Epoller()
    {
        if(_epfd >= 0)
        {
            close(_epfd);
        }
    }
private:
    int _epfd;
};